﻿using FlyingEye.Consts;
using FlyingEye.DeviceMaintenance;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;

namespace FlyingEye.EntityFrameworkCore
{
    public class DeviceOpsServiceDbContext : AbpDbContext<DeviceOpsServiceDbContext>
    {
        public DeviceOpsServiceDbContext(DbContextOptions<DeviceOpsServiceDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            FactoryModelBuilder.OnModelCreating(modelBuilder);
            ComeModelBuilder.OnModelCreating(modelBuilder);

            // 设备保养
            modelBuilder.Entity<DeviceMaintenanceModel>(builder =>
            {
                builder.ToTable(DeviceOpsServiceDbConsts.DbTablePrefix + "DeviceMaintenances",
                    DeviceOpsServiceDbConsts.DbSchema);

                // 设备主机下的设备名称要唯一
                builder.HasIndex(e => new { e.DeviceHostId, e.DeviceName })
                .IsUnique();

                // 配置从项目到部件无导航的一对多
                builder.HasMany<DevicePartModel>()
                .WithOne()
                .HasForeignKey(e => e.DeviceMaintenanceId)
                .IsRequired();

                // 配置从项目到成员无导航的一对多
                builder.HasMany<MaintenanceMemberModel>()
                .WithOne()
                .HasForeignKey(e => e.DeviceMaintenanceId)
                .IsRequired();
            });

            // 项目成员
            modelBuilder.Entity<MaintenanceMemberModel>(builder =>
            {
                builder.ToTable(DeviceOpsServiceDbConsts.DbTablePrefix + "MaintenanceMembers",
                    DeviceOpsServiceDbConsts.DbSchema);

                // 避免用户重复添加
                builder.HasIndex(e => new { e.DeviceMaintenanceId, e.ComeUserId })
                .IsUnique();
            });

            // 设备部件
            modelBuilder.Entity<DevicePartModel>(builder =>
            {
                builder.ToTable(DeviceOpsServiceDbConsts.DbTablePrefix + "DeviceParts",
                    DeviceOpsServiceDbConsts.DbSchema);

                // 配置从部件到维护记录无导航的一对多
                builder.HasMany<MaintenanceRecordModel>()
                .WithOne()
                .HasForeignKey(e => e.DevicePartId)
                .IsRequired();

                // 配置从部件到校验项无导航的一对多
                builder.HasMany<DevicePartCheckItemModel>()
                .WithOne()
                .HasForeignKey(e => e.DevicePartId)
                .IsRequired();

                // 一个部件有多个特征点
                builder.HasMany<DevicePartCharacteristicModel>()
                .WithOne()
                .HasForeignKey(e => e.DevicePartId)
                .IsRequired();

                // 使用部件名称做索引，保证唯一
                builder.HasIndex(e => new { e.DevicePartName, e.DeviceMaintenanceId })
                .IsUnique();
            });

            // 设备部件的特征点
            modelBuilder.Entity<DevicePartCharacteristicModel>(builder =>
            {
                builder.ToTable(DeviceOpsServiceDbConsts.DbTablePrefix + "DevicePartCharacteristics",
                   DeviceOpsServiceDbConsts.DbSchema);

                builder.HasIndex(e => new { e.DevicePartId, e.CharacteristicName })
                .IsUnique();
            });

            // 设备部件的 check 项
            modelBuilder.Entity<DevicePartCheckItemModel>(builder =>
            {
                builder.ToTable(DeviceOpsServiceDbConsts.DbTablePrefix + "DevicePartCheckItems",
                    DeviceOpsServiceDbConsts.DbSchema);

                // 描述要唯一
                builder.HasIndex(e => new { e.DevicePartId, e.Description }).IsUnique();

                // 配置校验项到需要校验的项一对一映射
                builder.HasMany<DevicePartCheckedResultModel>()
                .WithOne()
                .HasForeignKey(e => e.CheckItemId)
                .IsRequired();
            });

            // 保养记录
            modelBuilder.Entity<MaintenanceRecordModel>(builder =>
            {
                builder.ToTable(DeviceOpsServiceDbConsts.DbTablePrefix + "MaintenanceRecords",
                   DeviceOpsServiceDbConsts.DbSchema);

                // 配置从记录到已校验项无导航的一对多
                builder.HasMany<DevicePartCheckedResultModel>()
                .WithOne()
                .HasForeignKey(e => e.MaintenanceRecordId)
                .IsRequired();
            });

            // 保养记录的已经校验项
            modelBuilder.Entity<DevicePartCheckedResultModel>(builder =>
            {
                builder.ToTable(DeviceOpsServiceDbConsts.DbTablePrefix + "DevicePartCheckedResults",
                   DeviceOpsServiceDbConsts.DbSchema);
            });

            base.OnModelCreating(modelBuilder);
        }
    }
}
